package tech.wetech.admin3.util;

import cn.hutool.json.JSONObject;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.MediaType;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Component
public class LianduAPIUtils {
  private WebClient webClient;
  @Value("${liandu.key}")
  private String key;

  @Value("${liandu.api.getcount}")
  private String getcount;

  @Value("${liandu.domain}")
  private String domain;

  @Value("${liandu.api.getkeyexpdate}")
  private String getkeyexpdate;

  @Value("${liandu.api.create}")
  private String create;

  @Value("${liandu.api.createDigitalHumanCredential}")
  private String createDigitalHumanCredential;

  @Value("${liandu.api.sign}")
  private String sign;

  @Value("${liandu.api.query}")
  private String query;

  @Value("${liandu.api.save}")
  private String save;

  @PostConstruct
  public void init() {
    this.webClient = WebClient.builder()
      /**
       *  在Spring的生命周期中，使用@Value注解的变量将在构造器之后才被注入,导致因为null报错
       *  使用@PostConstruct注解在依赖注入完成后初始化WebClient
       */
      .baseUrl(domain)
      .build();
  }

  public JSONObject getcount(String reqpath){
    MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
    formData.add("reqpath", reqpath);
    return webClient.post()
      .uri(getcount)
      .header("key", key).bodyValue(formData)
      .retrieve()
      .bodyToMono(JSONObject.class)
      .block();
  }

  public JSONObject getkeyexpdate(){
    return webClient.get()
      .uri(getkeyexpdate)
      .header("key", key)
      .retrieve()
      .bodyToMono(JSONObject.class)
      .block();
  }

  public JSONObject create(){
    return webClient.post()
      .uri(create)
      .header("key", key)
      .retrieve()
      .bodyToMono(JSONObject.class)
      .block();
  }

  public JSONObject createDigitalHumanCredential(
    String ukey, String did, int seconds, Map<String, String> data
  ){
    JSONObject json = new JSONObject();
    json.put("did", did);
    json.put("seconds", seconds);
    json.put("data", data);

    return webClient.post()
      .uri(createDigitalHumanCredential)
      .contentType(MediaType.APPLICATION_JSON)
      .header("key",key)
      .header("ukey",ukey)
      .bodyValue(json)
      .retrieve()
      .bodyToMono(JSONObject.class)
      .block();
  }

  public Mono<String> postFormData(String path, String idNo, String idName, String mobile) {
    // 创建表单数据
    MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
    formData.add("idNo", idNo);
    formData.add("idName", idName);
    formData.add("mobile", mobile);

    // 发送POST请求
    return webClient.post()
      .uri(path)
      .contentType(MediaType.APPLICATION_FORM_URLENCODED)
      .header("key", key)
      .bodyValue(formData)
      .retrieve() // 开始处理响应
      .bodyToMono(String.class); // 将响应体转换为String
  }

  public CompletableFuture<JSONObject> personalThreeElementCheck(String personalCheckApi, String idNo, String idName, String mobile) {
    CompletableFuture<JSONObject> futureResult = new CompletableFuture<>();

    postFormData(personalCheckApi, idNo, idName, mobile).subscribe(response -> {
      JSONObject responseJson = new JSONObject(response);
      futureResult.complete(responseJson);
    });
    System.out.println(futureResult);

    return futureResult;
  }

  public CompletableFuture<JSONObject> companyThreeElementCheck(String path, String creditCode, String companyName, String legalPersonName) {
    // 创建表单数据
    MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
    formData.add("creditCode", creditCode);
    formData.add("companyName", companyName);
    formData.add("legalPersonName", legalPersonName);

    // 发送POST请求
    return webClient.post()
      .uri(path)
      .contentType(MediaType.APPLICATION_FORM_URLENCODED)
      .header("key", key)
      .bodyValue(formData)
      .retrieve() // 开始处理响应
      .bodyToMono(String.class) // 将响应体转换为String
      .map(response -> {
        JSONObject responseJson = new JSONObject(response);
        return responseJson;
      }) // 转换为JSONObject
      .toFuture(); // 将Mono转换为CompletableFuture
  }

  public CompletableFuture<JSONObject> saveAuth(String datahash, int datatime, String datainfo) {
    JSONObject json = new JSONObject();
    json.put("datahash", datahash);
    json.put("datatime", datatime);
    json.put("datainfo", datainfo);

    // 发送POST请求
    return webClient.post()
      .uri(save)
      .contentType(MediaType.APPLICATION_JSON)
      .header("key", key)
      .bodyValue(json)
      .retrieve() // 开始处理响应
      .bodyToMono(String.class) // 将响应体转换为String
      .map(response -> {
        JSONObject responseJson = new JSONObject(response);
        return responseJson;
      }) // 转换为JSONObject
      .toFuture(); // 将Mono转换为CompletableFuture
  }

  public JSONObject query(String txhash) {
    String uri = UriComponentsBuilder.fromUriString(query)
      .queryParam("txhash", txhash)
      .build()
      .toString();

    return webClient.get()
      .uri(uri)
      .header("key", key)
      .retrieve()
      .bodyToMono(JSONObject.class)
      .block();
  }

  public CompletableFuture<JSONObject> Sign(MultipartFile file, String signerCode, String signerName, String signerMobile,
                   String signerType, String page, String x, String y) throws IOException {
    // 创建一个MultipartBodyBuilder实例
    MultipartBodyBuilder builder = new MultipartBodyBuilder();
// 添加文件和其它表单字段
    builder.part("file", file.getBytes(), MediaType.MULTIPART_FORM_DATA)
      .filename(file.getOriginalFilename());
    builder.part("signerCode", signerCode);
    builder.part("signerName", signerName);
    builder.part("signerMobile", signerMobile);
    builder.part("signerType", signerType);
    builder.part("page", page);
    builder.part("x", x);
    builder.part("y", y);
    // 生成multipartBody作为请求体
    MultiValueMap<String, HttpEntity<?>> multipartBody = builder.build();

    return webClient.post()
      .uri(sign)
      .contentType(MediaType.MULTIPART_FORM_DATA)
      .header("key", key)
      .body(BodyInserters.fromMultipartData(multipartBody))
      .retrieve()
      .bodyToMono(String.class)
      .map(response -> new JSONObject(response))
      .onErrorResume(throwable -> { // 如果出现错误，则返回错误的JSONObject
        System.err.println("Error occurred: " + throwable.getMessage());
        return Mono.just(new JSONObject().put("error", "An error occurred while processing your request"));
      })
      .toFuture();
  }

}

